home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
muds
/
mordor_2.000
/
mordor_2
/
util
/
italk
/
italk.c
Wrap
C/C++ Source or Header
|
1994-11-13
|
12KB
|
542 lines
/* ITALK.C:Internet Talking: Copyright 1991, 1992 Steven D. Wallace */
/* Public domain. For non-commercial use only.
/* */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <sys/file.h>
#include <ctype.h>
#include <signal.h>
#define TIOCGETP _IOR(0, 8,struct sgttyb)/* get parameters -- gtty */
#define TIOCSETP _IOW(0, 9,struct sgttyb)/* set parameters -- stty */
/*
* Structure for TIOCGETP and TIOCSETP ioctls.
*/
#ifndef _SGTTYB_
#define _SGTTYB_
struct sgttyb {
char sg_ispeed; /* input speed */
char sg_ospeed; /* output speed */
char sg_erase; /* erase character */
char sg_kill; /* kill character */
short sg_flags; /* mode flags */
};
#endif
#if 1 /* 0 for computers that don't have h_addr_list in struct hostent */
#define h_addr h_addr_list[0] /* for backwards compatibilty */
#endif
#define HOSTFILE ".ithost"
#define FILE1 "/home/Isengard/mordor/bin/.lphost"
#define SDWFILE FILE1
#define MAXMACRO 100
#define MAXDIGIT 2
/* TERM.C */
extern void new_term(), old_term();
extern char get_key(), in_key();
extern errno;
int sock;
int df_i = 1;
int df_o = 2;
char quiet = 0;
void aborting();
void get_address();
void split_string();
main(argc, argv)
int argc;
char *argv[];
{
char address[30], port[10], path[80], startup[20], macro[20], blank[80];
char *address_ptr, *port_ptr, *startup_ptr, *macro_ptr;
int i = 0;
char command[MAXMACRO][80];
address[0] = port[0] = path[0] = startup[0] = macro[0] = blank[0] = 0;
signal(SIGPIPE,SIG_IGN);
i = 1;
if(i < argc) {
if(argv[i][0] == '-' && argv[i][1] == 'q') {
quiet = 1;
i++;
}
}
if(i < argc) {
strcpy(address, argv[i++]);
if(i < argc)
strcpy(port, argv[i++]);
}
else
get_address(address, port);
/* determine user's pathname to their .ithost file */
sprintf(path, "%s/%s", getenv("HOME"), HOSTFILE);
/* if no dot in address string argument, good chance it is a symbol */
if (!dot_in_string(address)) {
address_ptr = address;
/* if no valid port given as argument, read in new startup */
if (!*port)
port_ptr = port;
else
port_ptr = blank;
/* then look up address in .ithost in user's home directory */
if (!read_address(path, address, address_ptr, port_ptr, startup, macro))
/* not in their home directory, so try ~swallace/.lphost */
read_address(SDWFILE, address, address_ptr, port_ptr, startup, macro);
else
/* lookup good, see if address is a reference to global symbol */
if (*address == '!') {
if (*port != '!')
port_ptr = blank;
/* if no valid startup given, read in global startup */
if (!*startup || *startup == '#')
startup_ptr = startup;
else
startup_ptr = blank;
/* if no valid macro given, read in global startup */
if (!*macro || *macro == '#')
macro_ptr = macro;
else
macro_ptr = blank;
read_address(SDWFILE, address + 1, address_ptr, port_ptr, startup_ptr,
macro_ptr);
}
}
if (*port == '#') *port = 0;
if (*startup == '#') *startup = 0;
if (*macro == '#') *macro = 0;
/* printf("addr: %s, port: %s, startup: %s, macro: %s\n", address, port, start
up, macro); */
sock = connect_sock(address, port);
if (sock == -1)
aborting(3);
/* clear macros */
for(i=0; i != MAXMACRO; i++)
command[i][0] = 0;
/* determine user's pathname to their .macro or whatever file */
sprintf(path, "%s/%s", getenv("HOME"), macro);
/* read macro from user's file */
if(*macro)
if (read_macro(path, command) && !quiet)
fprintf(stderr, "Macros read from file %s.\n", path);
if (*startup) {
sprintf(path, "%s/%s", getenv("HOME"), startup);
write_file(path);
}
if (socket_io_handler(sock, command) == -1)
aborting(4);
}
int connect_sock(address, port)
char *address;
char *port;
{
int temp_int;
char name[80];
char number[20];
unsigned long addr;
unsigned long saddr;
struct sockaddr_in sin;
struct hostent *host;
if(isdigit(address[0])) {
if((addr = inet_addr(address)) == -1)
aborting(5);
else
saddr = ntohl(addr);
host = gethostbyaddr((char *)&saddr, sizeof(saddr), AF_INET);
if(host)
strncpy(name, host->h_name, 79);
else
strcpy(name, address);
strcpy(number, address);
}
else {
host = gethostbyname(address);
if(!host) aborting(6);
addr = *(long *)(host->h_addr);
strcpy(name, host->h_name);
saddr = ntohl(addr);
sprintf(number, "%d.%d.%d.%d",
(unsigned)(saddr)>>24,
(saddr & 0x00ff0000)>>16,
(saddr & 0x0000ff00)>>8,
(saddr & 0x000000ff));
}
sin.sin_addr.s_addr = addr;
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(port) ? atoi(port) : 23);
if(!quiet) {
if(*port)
fprintf(stderr, "Trying %s, port %s ...\n", number, port);
else
fprintf(stderr, "Trying %s ...\n", number);
}
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
return(-1);
}
if(connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("Connect");
return(-1);
}
temp_int = 1;
ioctl(sock, FIONBIO, &temp_int);
if(!quiet) {
if(*port)
fprintf(stderr, "Connected to %s, port %s.\n", name, port);
else
fprintf(stderr, "Connected to %s.\n", name);
}
return(sock);
}
int socket_io_handler(sock, command)
int sock;
char *command;
{
int readfds;
int len, i;
char echo = 1;
char buf[1024];
char *temp, tc;
struct sgttyb arg;
while(1) {
readfds = 1<<df_i | 1<<sock;
while(!select(16, &readfds, 0, 0, 0)) ;
if(readfds & (1<<df_i)) {
len = read(df_i, buf, 1023);
if(len == 0) aborting(1);
if( ( (buf[0] >= '0') && (buf[0] <= '9') ) &&
!( (buf[MAXDIGIT] >= '0') && (buf[MAXDIGIT] <= '9') ) ) {
tc = buf[MAXDIGIT];
buf[MAXDIGIT] = 0;
i = atoi(buf);
temp = command + i*80;
if(*temp && (i < MAXMACRO)) {
if(write(sock, temp, (len = strlen(temp))) < 0) {
perror("write sock");
return(0);
}
}
else {
buf[MAXDIGIT] = tc;
if(write(sock, buf, len) < 0) {
perror("write sock");
return(0);
}
}
}
else
if(write(sock, buf, len) < 0) {
perror("write sock");
return(0);
}
}
if(readfds & (1<<sock)) {
len = read(sock, buf, 1023);
if(len == 0) aborting(2);
if (buf[0] == -1) {
if (buf[1] == -5 && buf[2] == 1) {
ioctl(0,TIOCGETP,&arg); /* Get initial setup */
arg.sg_flags &= ~(ECHO); /* Turn off terminal ECHO */
ioctl(0,TIOCSETP,&arg); /* Store new settings */
echo = 0;
if (len > 3) if(write(df_o, buf+3, len-3) < 0) {
perror("write terminal");
return(0);
}
}
else if (buf[1] == -4 && buf[2] == 1) {
ioctl(0,TIOCGETP,&arg); /* Get initial setup */
arg.sg_flags |= (ECHO); /* Turn on terminal ECHO */
ioctl(0,TIOCSETP,&arg); /* Store new settings */
echo = 1;
if (len > 3) if(write(df_o, buf+3, len-3) < 0) {
perror("write terminal");
return(0);
}
}
else if(write(df_o, buf, len) < 0) {
perror("write terminal");
return(0);
}
} /* end FF special check */
else if(write(df_o, buf, len) < 0) { /* no FF, so output string */
perror("write terminal");
return(0);
}
if(!echo) {
for(i = 0; i < len-2; i++)
if(buf[i] == -1)
if(buf[i] == -1 && buf[i+1] == -4 && buf[i+2] == 1) {
ioctl(0,TIOCGETP,&arg); /* Get initial setup */
arg.sg_flags |= (ECHO); /* Turn on terminal ECHO */
ioctl(0,TIOCSETP,&arg); /* Store new settings */
echo = 1;
}
} /* end no echo to echo check */
} /* end socket out check */
} /* end infinite loop */
} /* end io_handler */
void get_address(address, port)
char *address;
char *port;
{
char buf[51];
write_msg("Destination: ");
read_msg(buf,50);
split_string(buf, address, port);
}
void split_string(str_in, str_one, str_two)
char *str_in;
char *str_one;
char *str_two;
{
int i=0, j=0;
while(str_in[i] != ' ' && str_in[i] != '\n' && str_in[i] != 0)
str_one[j++] = str_in[i++];
str_one[j]=0; j=0;
while(str_in[i] == ' ' || str_in[i] == '\n') i++;
if(str_in[i])
while(str_in[i] != 0 && str_in[i] != '\n')
str_two[j++] = str_in[i++];
str_two[j]=0;
}
int dot_in_string(str)
char *str;
{
int i=0;
while (str[i++] != 0)
if (str[i-1] == '.')
return(1);
return(0);
}
int read_macro(fname, command)
char *fname;
char *command;
{
FILE *fp;
char buf[81];
char numbuf[21];
char *temp;
int num, i;
if((fp=fopen(fname, "r")) == 0)
return(0);
while(!feof(fp)) {
fgets(buf, sizeof(buf), fp);
if(*buf == '#')
continue;
split_string(buf, numbuf, buf);
num = atoi(numbuf);
temp = command + num*80;
if(num) {
strcpy(temp, buf);
num = strlen(temp);
/* replace all '\' with CR/LF? */
for (i = 0; i != num; i++) {
if (temp[i] == '\\')
temp[i] = 13;
}
/* add CR to end of string */
if (temp[num-1] != 13) {
temp[num] = 13;
num = num +1;
}
temp[num] = 0;
}
}
fclose(fp);
return(1);
}
int read_address(fname, symbol, address, port, startup, macro)
char *fname;
char *symbol;
char *address;
char *port;
char *startup;
char *macro;
{
FILE *fp;
char buf[81];
char cur_symbol[21];
int i;
if((fp=fopen(fname, "r")) == 0)
return(0);
while(!feof(fp)) {
fgets(buf, sizeof(buf), fp);/* get rest of line (address, port) */
split_string(buf, cur_symbol, buf);
/* check to see if parameter matches current symbol in line */
for (i=0; symbol[i] != 0; i++)
if (symbol[i] != cur_symbol[i])
break;
if (symbol[i] == cur_symbol[i]) {
fclose(fp);
split_string(buf, address, buf);
if(*buf) split_string(buf, port, buf);
if(*buf) split_string(buf, startup, buf);
if(*buf) split_string(buf, macro, buf);
return(1);
}
}
fclose(fp);
return(0);
}
int write_file(path)
char *path;
{
int fd;
long count;
char buf[1024];
fd = open(path, O_RDONLY, 0);
if(fd < 0) return(0);
if(!quiet)
fprintf(stderr, "Sending file %s to remote host.\n", path);
while(1) {
count = read(fd, buf, sizeof(buf));
if(count)
write(sock, buf, count);
else
break;
}
return(1);
}
write_msg(str)
char *str;
{
write(df_o, str, strlen(str));
}
write_sock(str)
char *str;
{
write(sock, str, strlen(str));
}
read_msg(str,slen)
char *str;
int slen;
{
int readfds;
int num=0, len;
char ch;
do {
readfds = 1<<df_i;
while(!select(16, &readfds, 0, 0, 0)) ;
len = read(df_i, &ch, 1);
if(len == 0) aborting(0);
if(ch == 10 || num==slen-1) ch = 0;
if(ch != 13) str[num++] = ch;
} while(ch);
}
void aborting(arg)
int arg;
{
switch (arg) {
case 1:
fprintf(stderr, "\nConnection closed by local host.\n");
break;
case 2:
fprintf(stderr, "\nConnection closed by remote host.\n");
break;
case 3:
fprintf(stderr, "\nUnable to connect to remote host.\n");
break;
case 4:
fprintf(stderr, "\nProblems with sockets. Connection closed.\n");
break;
case 5:
fprintf(stderr, "\nInvalid host number.\n");
break;
case 6:
fprintf(stderr, "\nInvalid host name.\n");
break;
default:
fprintf(stderr, "Connection closed (%d).\n",arg);
}
signal(SIGPIPE,SIG_IGN);
close(sock); close(df_i); close(df_o);
exit(0);
}